using Engine.Graphics;
using Engine.Graphics.VertexStructures;
using SharpDX;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace Engine.FileFormats3D
{
    public struct Mesh3dData
    {
        #region Private Fields

        private List<ushort> indices;
        private List<Material> materials;
        private List<int> polyTextures;
        private List<MyOwnVertex.MyPositionNormalTextured> vertices;

        #endregion Private Fields

        #region Public Constructors

        public Mesh3dData(List<Material> materials)
        {
            this.indices = new List<ushort>();
            this.vertices = new List<MyOwnVertex.MyPositionNormalTextured>();
            this.polyTextures = new List<int>();
            this.materials = new List<Material>(materials);
            for (int i = 0; i < this.materials.Count; i++)
            {
                polyTextures.Add(0);
            }
        }

        public Mesh3dData(MaterialManager materialManager, Meshobject mesh)
        {
            this.indices = new List<ushort>(mesh.Indices);
            this.vertices = new List<MyOwnVertex.MyPositionNormalTextured>(mesh.Vertices);
            this.polyTextures = new List<int>(mesh.UsedPolysForMaterial);
            this.materials = new List<Material>();
            for (int i = 0; i < mesh.materialsIDs.Length; i++)
            {
                this.materials.Add(materialManager.GetMaterial(mesh.materialsIDs[i]));
            }
        }

        public Mesh3dData(List<ushort> indices, List<MyOwnVertex.MyPositionNormalTextured> vertices, List<int> numberOfPolysForTexture, List<Material> materials)
        {
            this.indices = new List<ushort>(indices);
            this.vertices = new List<MyOwnVertex.MyPositionNormalTextured>(vertices);
            this.polyTextures = new List<int>(numberOfPolysForTexture);
            this.materials = new List<Material>(materials);
        }

        #endregion Public Constructors

        #region Public Properties

        //private float minX, maxX, minZ, maxZ;
        public List<ushort> Indices
        {
            get { return indices; }
            set { indices = value; }
        }

        public List<Material> Materials
        {
            get { return materials; }
            set { materials = value; }
        }

        public List<int> PolyTextures
        {
            get { return polyTextures; }
            set { polyTextures = value; }
        }

        public List<MyOwnVertex.MyPositionNormalTextured> Vertices
        {
            get { return vertices; }
            set { vertices = value; }
        }

        #endregion Public Properties

        #region Public Methods

        public static Mesh3dData CreateForestBorder(Vector3[] middle, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, ref float textureUcoordinates, float textureScale, Material materialID_For_Trees)
        {
            Array.Reverse(middle);

            List<int> polyTextures = new List<int>();
            List<ushort> indices = new List<ushort>();
            List<MyOwnVertex.MyPositionNormalTextured> vertices = new List<MyOwnVertex.MyPositionNormalTextured>();
            short OffsetIndices = (short)(vertices.Count);

            polyTextures.Add((middle.Length - 1) * 4);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));

                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0],
                Vector3.Zero,
                textureUcoordinates, 0f,
                textureUcoordinates, 0f,
                new Color4(0, 0, 0, 0)));

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] + rightPoint,
                Vector3.UnitY,
                textureUcoordinates, -1f,
                textureUcoordinates, -1f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates -= (middleLineDistances[0] / widthPointOne) * textureScale;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));

                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);

                //normal = GeoMath.Normal2Poly(middle[i + 1], middle[i] - rightPoint, middle[i] + rightPoint);
                //normal += GeoMath.Normal2Poly(middle[i - 1], middle[i] + rightPoint, middle[i] - rightPoint);
                //normal.Normalize();

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i],
                    Vector3.Zero,
                    textureUcoordinates, 0.0f,
                    textureUcoordinates, 0.0f,
                    new Color4(0, 0, 0, 0)));
                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i] + rightPoint,
                    Vector3.UnitY,
                    textureUcoordinates, -1.0f,
                    textureUcoordinates, -1.0f,
                    new Color4(0, 0, 0, 0)));

                textureUcoordinates -= (middleLineDistances[i] / streetwidth) * textureScale;
            }
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1],
                Vector3.Zero,
                textureUcoordinates, 0.0f,
                textureUcoordinates, 0.0f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] + rightPoint,
                Vector3.UnitY,
                textureUcoordinates, -1.0f,
                textureUcoordinates, -1.0f,
                new Color4(0, 0, 0, 0)));
            //textureUcoordinates -= middleLineDistances[middleLineDistances.Length - 1] * (2.0f / widthPointTwo) * textureScale;

            return new Mesh3dData(indices, vertices, polyTextures, new List<Material>() { materialID_For_Trees });
        }

        public static Mesh3dData CreateGuardRail(Vector3[] middle, decimal anglePointOne, decimal anglePointTwo, bool p, bool p_9, float textureUcoordinates, Material materialID_ForRail)
        {
            List<ushort> indices = new List<ushort>();
            List<MyOwnVertex.MyPositionNormalTextured> vertices = new List<MyOwnVertex.MyPositionNormalTextured>();

            List<Material> materialIDs = new List<Material>();

            Vector3[] middleLine = MiddleLine.CreateNewMiddleLineSegments(middle, 300.0f, 7.0f);
            Vector3[] left = MiddleLine.CreateNewMiddleLine(middleLine, anglePointOne, anglePointTwo, -1.25f, -1.25f, 0, 0, 0);
            Vector3[] left2 = MiddleLine.CreateNewMiddleLine(middleLine, anglePointOne, anglePointTwo, -1.0f, -1.0f, 0, 0, 0);
            Vector3[] rightTemp = MiddleLine.CreateNewMiddleLine(middleLine, anglePointOne, anglePointTwo, 0.0f, 0.0f, 0, 0, 0);

            //Reverse the right lane
            Vector3[] right = new Vector3[rightTemp.Length];
            for (int i = 0; i < right.Length; i++)
            {
                right[right.Length - (i + 1)] = rightTemp[i];
            }

            //left and right side
            List<int> polysPerTexture = new List<int>();
            polysPerTexture.Add(0);
            CreateGuardRailPart1(ref left, ref vertices, ref indices, ref polysPerTexture, anglePointOne, anglePointTwo, 14.0f, 14.0f, -90, -90, textureUcoordinates);
            Vector3[] leftReverse = new Vector3[left2.Length];
            for (int i = 0; i < leftReverse.Length; i++)
            {
                leftReverse[leftReverse.Length - (i + 1)] = left2[i];
            }
            Mesh3dData.CreateGuardRailPart1(ref leftReverse, ref vertices, ref indices, ref polysPerTexture, anglePointOne, anglePointTwo, 14.0f, 14.0f, -90, -90, textureUcoordinates);
            Mesh3dData.CreateGuardRailPart2(ref right, ref vertices, ref indices, ref polysPerTexture, anglePointOne, anglePointTwo, 10, 10, -90, -90, textureUcoordinates);

            //Top
            CreateGuardRailPart3(ref middleLine, ref vertices, ref indices, ref polysPerTexture, anglePointOne, anglePointTwo, 1.25f, 1.25f, 0, 0, textureUcoordinates);

            materialIDs.Add(materialID_ForRail);

            return new Mesh3dData(indices, vertices, polysPerTexture, materialIDs);//, mappingMode);
        }

        public static Mesh3dData CreateSimpleRoad(Vector3[] middle, decimal anglePointOne, decimal anglePointTwo,
            float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationMiddle, float inclinationPointTwo,
            float textureUcoordinates, Material materialID_ForRoad,
            System.Drawing.Color vertexColorStartLeft, System.Drawing.Color vertexColorEndLeft, System.Drawing.Color vertexColorStartRight, System.Drawing.Color vertexColorEndRight)
        {
            Vector3 normal;
            List<int> polyTextures = new List<int>();
            List<ushort> indices = new List<ushort>();
            List<MyOwnVertex.MyPositionNormalTextured> vertices = new List<MyOwnVertex.MyPositionNormalTextured>();

            short OffsetIndices = (short)(vertices.Count);

            polyTextures.Add((middle.Length - 1) * 4);

            float lengthOfStreet = 0.0f;
            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = MiddleLine.CalculateDistanceBetweenSegments(middle, out lengthOfStreet);

            //lengthOfStreet *= 0.5f;

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1); i2++)
            {
                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 4 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));
                indices.Add((ushort)(point + 5 + OffsetIndices));

                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 4 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 5 + OffsetIndices));
                indices.Add((ushort)(point + 4 + OffsetIndices));
                point += 3;
            }

            Vector3 rightPoint; //Is a tempoary Point
            float currentDistanceOnRoad = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            normal = GeoMath.Normal2Poly(middle[1], middle[0] - rightPoint, middle[0] + rightPoint);

            // Left Point

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] - rightPoint,
                normal,
                0.0f, textureUcoordinates,
                0.0f, textureUcoordinates,
                new Color4((float)vertexColorStartLeft.R / 255.0f,
                    (float)vertexColorStartLeft.G / 255.0f,
                    (float)vertexColorStartLeft.B / 255.0f,
                    0)));

            // Middle Point

            Color4 mixedColor = new Color4((float)(vertexColorStartLeft.R + vertexColorStartRight.R) / (255.0f * 2.0f),
                (float)(vertexColorStartLeft.G + vertexColorStartRight.G) / (255.0f * 2.0f),
                (float)(vertexColorStartLeft.B + vertexColorStartRight.B) / (255.0f * 2.0f)
                , 0);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
              middle[0],
              normal,
              -0.5f, textureUcoordinates,
              -0.5f, textureUcoordinates,
              mixedColor));

            // Right Point
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] + rightPoint, // Position
                normal, // normal
                -1.0f, textureUcoordinates, // Texture coordinates #1
                -1.0f, textureUcoordinates, // Texture coordinates #2
                 new Color4((float)vertexColorStartRight.R / 255.0f,
                    (float)vertexColorStartRight.G / 255.0f,
                    (float)vertexColorStartRight.B / 255.0f,
                    0))); // Vertex blend color

            textureUcoordinates += middleLineDistances[0] / 100;

            for (int i = 1; i < (middle.Length - 1); i++)
            {
                currentDistanceOnRoad += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (currentDistanceOnRoad / lengthOfStreet));

                if (currentDistanceOnRoad / lengthOfStreet < 0.50f)
                    inclination = inclinationPointOne + ((inclinationMiddle - inclinationPointOne) * (currentDistanceOnRoad * 2.0f / lengthOfStreet));
                else
                    inclination = inclinationMiddle - ((inclinationPointTwo - inclinationMiddle) * (1.0f - (currentDistanceOnRoad * 2.0f / lengthOfStreet)));

                float currentDistanceOnRoadInPercent = (currentDistanceOnRoad / lengthOfStreet);
                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);

                normal = GeoMath.Normal2Poly(middle[i + 1], middle[i] - rightPoint, middle[i] + rightPoint);
                normal += GeoMath.Normal2Poly(middle[i - 1], middle[i] + rightPoint, middle[i] - rightPoint);
                normal.Normalize();

                Color4 mixedColorStartEndLeft = new Color4()
                {
                    Alpha = 0,//(vertexColorEndLeft.A * currentDistanceOnRoadInPercent + vertexColorStartLeft.A * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Red = (vertexColorEndLeft.R * currentDistanceOnRoadInPercent + vertexColorStartLeft.R * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Green = (vertexColorEndLeft.G * currentDistanceOnRoadInPercent + vertexColorStartLeft.G * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Blue = (vertexColorEndLeft.B * currentDistanceOnRoadInPercent + vertexColorStartLeft.B * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f
                };

                Color4 mixedColorStartEndRight = new Color4()
                {
                    Alpha = 0,//(vertexColorEndRight.A * currentDistanceOnRoadInPercent + vertexColorStartRight.A * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Red = (vertexColorEndRight.R * currentDistanceOnRoadInPercent + vertexColorStartRight.R * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Green = (vertexColorEndRight.G * currentDistanceOnRoadInPercent + vertexColorStartRight.G * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f,
                    Blue = (vertexColorEndRight.B * currentDistanceOnRoadInPercent + vertexColorStartRight.B * (1.0f - currentDistanceOnRoadInPercent)) / 255.0f
                };

                Color4 mixedColorStartEndMiddle = new Color4()
                {
                    Alpha = 0,// (mixedColorStartEndRight.Alpha + mixedColorStartEndLeft.Alpha) / 2.0f,
                    Red = (mixedColorStartEndRight.Red + mixedColorStartEndLeft.Red) / 2.0f,
                    Green = (mixedColorStartEndRight.Green + mixedColorStartEndLeft.Green) / 2.0f,
                    Blue = (mixedColorStartEndRight.Blue + mixedColorStartEndLeft.Blue) / 2.0f,
                };

                // Left vertex
                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                     middle[i] - rightPoint,  // Position
                     normal, // normal
                   0.0f, textureUcoordinates, // Texture coordinates #1
                    0.0f, textureUcoordinates, // Texture coordinates #2
                    mixedColorStartEndLeft // Vertex blend color
                ));

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i], // Position
                    normal, // normal
                    -0.5f, textureUcoordinates, // Texture coordinates #1
                    -0.5f, textureUcoordinates, // Texture coordinates #2
                   mixedColorStartEndMiddle)); // Vertex blend color

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i] + rightPoint, // Position
                    normal, // normal
                    -1.0f, textureUcoordinates, // Texture coordinates #1
                    -1.0f, textureUcoordinates, // Texture coordinates #2
                    mixedColorStartEndRight)); // Vertex blend color

                if (i < middle.Length - 1)
                    textureUcoordinates += middleLineDistances[i] / 100;
            }

            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);
            normal = GeoMath.Normal2Poly(middle[middle.Length - 2], middle[middle.Length - 1] + rightPoint, middle[middle.Length - 1] - rightPoint);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] - rightPoint, // Position
                normal, // Normal
                0.0f, textureUcoordinates, // TextureCoordinates #1
                0.0f, textureUcoordinates, // TextureCoordinates #2
                 new Color4((float)vertexColorEndLeft.R / 255.0f,
                    (float)vertexColorEndLeft.G / 255.0f,
                    (float)vertexColorEndLeft.B / 255.0f,
                    0))); // Vertex blend color

            mixedColor = new Color4((float)(vertexColorEndLeft.R + vertexColorEndRight.R) / (255.0f * 2.0f),
                (float)(vertexColorEndLeft.G + vertexColorEndRight.G) / (255.0f * 2.0f),
                (float)(vertexColorEndLeft.B + vertexColorEndRight.B) / (255.0f * 2.0f),
                0);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1], // Position
                normal, // Normal
                -0.5f, textureUcoordinates, // TextureCoordinates #1
                -0.5f, textureUcoordinates, // TextureCoordinates #2
                 mixedColor)); // Vertex blend color

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] + rightPoint,
                normal,
                -1.0f, textureUcoordinates,
                -1.0f, textureUcoordinates,
                 new Color4((float)vertexColorEndRight.R / 255.0f,
                    (float)vertexColorEndRight.G / 255.0f,
                    (float)vertexColorEndRight.B / 255.0f,
                    0)));

            List<Material> materialIDs = new List<Material>();
            materialIDs.Add(materialID_ForRoad);
            List<EnumMappingMode> mappingMode = new List<EnumMappingMode>();
            mappingMode.Add(EnumMappingMode.material32);

            return new Mesh3dData(indices, vertices, polyTextures, new List<Material>() { materialID_ForRoad });//, mappingMode);
        }

        public static Mesh3dData FromStream(BinaryReader br)
        {
            // Read the Header (26 Bytes)
            string ident = new string(br.ReadChars(14));
            if (ident != "MeshForAddin 1")
            {
                MessageBox.Show("error in Loading!!");
            }
            Mesh3dData mesh = new Mesh3dData(new List<Material>() { });
            int nIndices = br.ReadInt32();
            int nVerts = br.ReadInt32();
            int nMaterials = br.ReadInt32();

            // Read Indices (each 2 Bytes)
            for (int i = 0; i < nIndices; i++)
            {
                mesh.indices.Add(br.ReadUInt16());
            }
            // Read vertices
            for (int v = 0; v < nVerts; v++)
            {
                MyOwnVertex.MyPositionNormalTextured vertex = MyOwnVertex.MyPositionNormalTextured.FromStream(br);
                vertex.VertexColor = new Color4()
                {
                    Alpha = 0.0f,// Clear WR2 Shadow
                    Red = vertex.VertexColor.Red,
                    Green = vertex.VertexColor.Green,
                    Blue = vertex.VertexColor.Blue
                };
                vertex.DiffuseColor = new Color4()
                {
                    Alpha = 1.0f,
                    Red = 0.4f,
                    Green = 0.4f,
                    Blue = 0.4f
                };
                mesh.vertices.Add(vertex);
            }

            // Read the materials and the number of polygons
            for (int m = 0; m < nMaterials; m++)
            {
                // Number of polygons which must painted with this material
                mesh.polyTextures.Add(br.ReadInt32());
                // Write the Material
                mesh.materials.Add(Material.FromStream(br));
            }

            return mesh;
        }

        public static Mesh3dData Transform(ref Mesh3dData mesh, decimal angle, Vector3 centerOfCross)
        {
            Mesh3dData transformedMesh = new Mesh3dData();
            transformedMesh.vertices = new List<MyOwnVertex.MyPositionNormalTextured>(mesh.Vertices);
            transformedMesh.Indices = new List<ushort>(mesh.Indices);
            transformedMesh.Materials = new List<Material>(mesh.Materials);
            transformedMesh.PolyTextures = new List<int>(mesh.PolyTextures);
            MyOwnVertex.MyPositionNormalTextured vertex;

            Matrix matrix = Matrix.Identity;
            matrix = Matrix.RotationY((float)angle * (float)(Math.PI / 180));

            for (int v = 0; v < transformedMesh.Vertices.Count; v++)
            {
                vertex = transformedMesh.Vertices[v];
                vertex.Position = Vector3.TransformCoordinate(vertex.Position, matrix);
                vertex.Position = Vector3.Multiply(vertex.Position, 1.0f) + centerOfCross;
                transformedMesh.Vertices[v] = vertex;
            }

            return transformedMesh;
        }

        public static Mesh3dData Transform(ref Mesh3dData mesh, ref List<Vector3> middleline, ref List<Vector2> inclinationVectors, bool inverseInclination, ref Vector3 directionStart, ref Vector3 directionEnd, bool ScaleToSegmentLength, float minX, float maxX)
        {
            float xOffset = 0;
            Mesh3dData transformedMesh = new Mesh3dData();
            transformedMesh.vertices = new List<MyOwnVertex.MyPositionNormalTextured>(mesh.Vertices);
            transformedMesh.Indices = new List<ushort>(mesh.Indices);
            transformedMesh.Materials = new List<Material>(mesh.Materials);
            transformedMesh.PolyTextures = new List<int>(mesh.PolyTextures);

            // Calculate distances between
            List<float> distancesMiddleLine = new List<float>();
            List<Vector3> directionToNextPoint = new List<Vector3>();
            List<Vector3> middleLinePositionForEachVertex = new List<Vector3>();
            float distance = 0;

            for (int i = 0; i < transformedMesh.vertices.Count; i++)
            {
                xOffset = Math.Min(xOffset, transformedMesh.Vertices[i].X);
            }

            /* Use the smallest X value. */
            xOffset = Math.Min(minX, xOffset);

            //transformedMesh.ScaleX(2.0f);
            float meshLengthX = 0;
            for (int i = 0; i < transformedMesh.vertices.Count; i++)
            {
                MyOwnVertex.MyPositionNormalTextured vertex = transformedMesh.Vertices[i];
                vertex.X = Math.Max(0, vertex.X - xOffset);
                transformedMesh.Vertices[i] = vertex;
                meshLengthX = Math.Max(meshLengthX, vertex.X);
            }

            /* Get the complete Segment Length. */
            meshLengthX = Math.Max(maxX - minX, meshLengthX);

            distancesMiddleLine.Add(0); // first Point starts at zero.
            for (int i = 0; i < middleline.Count - 1; i++)
            {
                distance += GeoMath.DistanceBtw2Points(middleline[i], middleline[i + 1]);
                distancesMiddleLine.Add(distance);
            }

            if (ScaleToSegmentLength && distancesMiddleLine[1] > 0.0f)
            {
                transformedMesh.ScaleX(distancesMiddleLine[1] / meshLengthX);
                for (int i = 0; i < transformedMesh.Vertices.Count; i++)
                {
                    MyOwnVertex.MyPositionNormalTextured temp = transformedMesh.Vertices[i];
                    temp.Position.X = Math.Min(temp.Position.X, distancesMiddleLine[1]);
                    transformedMesh.vertices[i] = temp;
                }
            }
            else if (meshLengthX / distance > 1) // Scale down
            {
                transformedMesh.ScaleX(distance / meshLengthX);
                meshLengthX = distance;

                for (int i = 0; i < transformedMesh.Vertices.Count; i++)
                {
                    MyOwnVertex.MyPositionNormalTextured temp = transformedMesh.Vertices[i];
                    temp.Position.X = Math.Min(temp.Position.X, distance);
                    transformedMesh.vertices[i] = temp;
                }
            }

            // Calculates the directions
            directionToNextPoint.Add(directionStart);
            for (int i = 1; i < middleline.Count - 1; i++)
            {
                Vector3 direction = middleline[i + 1] - middleline[i - 1];
                directionToNextPoint.Add(Vector3.Normalize(direction));
            }
            directionToNextPoint.Add(directionEnd);

            // Add all possible x-coordinates to zhe list.
            List<float> allXPositions = new List<float>();
            for (int i = 0; i < transformedMesh.Vertices.Count; i++)
            {
                float xPosition = transformedMesh.vertices[i].X;
                if (!allXPositions.Contains(xPosition))
                    allXPositions.Add(xPosition);
            }
            if (transformedMesh.vertices.Count == 0)
            {
                allXPositions.Add(meshLengthX);
            }

            allXPositions.Sort();
            // Add the x Positions to the  middleLine
            for (int i = 0; i < allXPositions.Count; i++)
            {
                if (!distancesMiddleLine.Contains(allXPositions[i]))
                {
                    for (int j = 0; j < distancesMiddleLine.Count; j++)
                    {
                        if (allXPositions[i] < distancesMiddleLine[j])
                        {
                            //Add the new XPosition to the middleline and calculate the angle and all
                            // other data if needed.
                            float value = (allXPositions[i] - distancesMiddleLine[j - 1]) / (distancesMiddleLine[j] - distancesMiddleLine[j - 1]);
                            float distanceToPreviewPoint = allXPositions[i] - distancesMiddleLine[j - 1];
                            Vector3 differenceVector = Vector3.Subtract(directionToNextPoint[j], directionToNextPoint[j - 1]);
                            distancesMiddleLine.Insert(j, allXPositions[i]);

                            // add a new Point to the middleLine.
                            Vector3 direction = Vector3.Normalize(middleline[j] - middleline[j - 1]);
                            middleline.Insert(j, middleline[j - 1] + direction * distanceToPreviewPoint);

                            // insert new inclination Point.
                            inclinationVectors.Insert(j, Vector2.Add(inclinationVectors[j - 1], (Vector2.Multiply(inclinationVectors[j] - inclinationVectors[j - 1], value))));

                            // insert new direction to next point.
                            directionToNextPoint.Insert(j, Vector3.Subtract(directionToNextPoint[j], differenceVector * (1.0f - value)));
                            break;
                        }
                    }
                }
            }

            int lastUsedMiddleLinePoint = 0;
            for (int i = 0; i < transformedMesh.Vertices.Count; i++)
            {
                MyOwnVertex.MyPositionNormalTextured vertex = transformedMesh.Vertices[i];

                int index = distancesMiddleLine.IndexOf(transformedMesh.Vertices[i].X);

                if (index == -1)
                    index = middleline.Count - 1;

                lastUsedMiddleLinePoint = Math.Max(lastUsedMiddleLinePoint, index);
                Vector3 positionOnMiddleLine = middleline[index];
                Vector3 directionVector = directionToNextPoint[index];
                directionVector.Normalize();
                Vector2 inclinationOfRoad = inclinationVectors[index];

                Vector2 direction2D = new Vector2(directionVector.X, directionVector.Z);
                direction2D.Normalize();

                float length = (float)Math.Sqrt(directionVector.X * directionVector.X + directionVector.Z * directionVector.Z) - (float)Math.Sqrt(directionVector.Y * directionVector.Y);

                // Start with the middleroad position
                vertex.Position = positionOnMiddleLine;

                // add the mesh vertex postion
                Vector3 vertexAfterInclination = GeoMath.AddInclinationToVector3(inverseInclination, inclinationOfRoad, mesh.vertices[i].Position);
                Vector3 normaleAfterInclination = GeoMath.AddInclinationToVector3(inverseInclination, inclinationOfRoad, mesh.vertices[i].Normal);

                vertex.Position.X += -direction2D.Y * vertexAfterInclination.Z;
                vertex.Position.Y += vertexAfterInclination.Y * (length + Math.Abs(directionVector.Y));
                vertex.Position.Z += direction2D.X * vertexAfterInclination.Z;

                // add the inclination
                vertex.Position.X += vertexAfterInclination.Y * directionVector.Y * (-directionVector.X); //+ mesh.vertices[i].Y * inclinationOfRoad.Y;
                vertex.Position.Z += vertexAfterInclination.Y * directionVector.Y * (-directionVector.Z);// +mesh.vertices[i].Y * inclinationOfRoad.Y;

                // Calculate the normal
                vertex.Normal.X = -direction2D.Y * normaleAfterInclination.Z;
                vertex.Normal.Y = normaleAfterInclination.Y * (length + Math.Abs(directionVector.Y));
                vertex.Normal.Z = direction2D.X * normaleAfterInclination.Z;
                vertex.Normal.X += normaleAfterInclination.Y * directionVector.Y * (-directionVector.X);
                vertex.Normal.Z += normaleAfterInclination.Y * directionVector.Y * (-directionVector.Z);
                vertex.Normal.Normalize();

                transformedMesh.Vertices[i] = vertex;
            }

            // When the road have no mesh we will use the max size.
            if (transformedMesh.vertices.Count == 0)
            {
                int index = distancesMiddleLine.IndexOf(meshLengthX);

                if (index == -1)
                    index = middleline.Count - 1;

                lastUsedMiddleLinePoint = Math.Max(lastUsedMiddleLinePoint, index);
                Vector3 positionOnMiddleLine = middleline[index];
                Vector3 directionVector = directionToNextPoint[index];
                directionVector.Normalize();
            }

            middleline.RemoveRange(0, lastUsedMiddleLinePoint);
            directionToNextPoint.RemoveRange(0, lastUsedMiddleLinePoint);
            inclinationVectors.RemoveRange(0, lastUsedMiddleLinePoint);

            if (middleline.Count == 1)
                middleline.Clear();

            if (directionToNextPoint.Count > 1)
            {
                directionStart = directionToNextPoint[0];
                directionEnd = directionToNextPoint[directionToNextPoint.Count - 1];
            }

            return transformedMesh;
        }

        public void AddMesh(Mesh3dData mesh)
        {
            ushort currentNumberVertices = (ushort)this.vertices.Count;

            // Add all Vertices to the current mesh
            this.vertices.AddRange(mesh.vertices);

            // update the mesh indices and add the current count of vertices to the values
            for (int i = 0; i < mesh.indices.Count; i++)
            {
                mesh.indices[i] += currentNumberVertices;
            }

            for (int t = 0; t < mesh.materials.Count; t++)
            {
                AddPolygons(mesh.materials[t], mesh.polyTextures[t], mesh);
            }
        }

        public void Dispose()
        {
            this.indices.Clear();
            this.indices = null;
            this.materials.Clear();
            this.materials = null;
            this.polyTextures.Clear();
            this.polyTextures = null;
            this.vertices.Clear();
            this.vertices = null;
        }

        public void RemoveUnusedVertices()
        {
            bool[] usedVertices = new bool[this.vertices.Count];

            // Get the list of used vertices
            for (int i = 0; i < this.indices.Count; i++)
            {
                usedVertices[this.indices[i]] = true;
            }

            // Remove unused vertices
            for (int i = this.vertices.Count - 1; i >= 0; i--)
            {
                if (!usedVertices[i])
                {
                    this.vertices.RemoveAt(i);

                    for (int j = 0; j < this.indices.Count; j++) // give the index list new ids for vertices.
                    {
                        if (this.indices[j] > i)
                            this.indices[j]--;
                    }
                }
            }
        }

        public void Rotation(Matrix rotation)
        {
            MyOwnVertex.MyPositionNormalTextured vertex;
            for (int v = 0; v < this.Vertices.Count; v++)
            {
                vertex = this.Vertices[v];
                vertex.Position = Vector3.TransformCoordinate(vertex.Position, rotation);
                vertex.Normal = Vector3.TransformCoordinate(vertex.Normal, rotation);
                this.Vertices[v] = vertex;
            }
        }

        public void SaveToStream(BinaryWriter bw, MaterialManager materialManager)
        {
            // Write Header (26 Bytes)
            bw.Write("MeshForAddin 1".ToCharArray());   //14 Bytes Identy
            bw.Write(this.indices.Count);               // 4 Bytes Number of indices
            bw.Write(this.vertices.Count);              // 4 Bytes Number of vertices
            bw.Write(this.materials.Count);             // 4 Bytes Number of materials

            // Write Indices (each 2 Bytes)
            for (int i = 0; i < this.indices.Count; i++)
            {
                bw.Write(this.indices[i]);
            }

            // Write vertices
            for (int v = 0; v < this.vertices.Count; v++)
            {
                this.vertices[v].SaveToStream(bw);
            }

            // Write the materials and the number of polygons
            for (int m = 0; m < this.materials.Count; m++)
            {
                // Number of polygons which must painted with this material
                bw.Write(this.polyTextures[m]);
                // Write the Material
                this.materials[m].SaveToStream(bw);
            }
        }

        #endregion Public Methods

        #region Private Methods

        private static void CreateGuardRailPart1(ref Vector3[] middle, ref List<MyOwnVertex.MyPositionNormalTextured> vertices, ref List<ushort> indices, ref List<int> polyTextures, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, float textureUcoordinates)
        {
            short OffsetIndices = (short)(vertices.Count);

            polyTextures[0] += ((middle.Length - 1) * 2);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0],
                Vector3.Zero,
                textureUcoordinates, 0.25f,
                textureUcoordinates, 0.25f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] + rightPoint,
                Vector3.Zero,
                textureUcoordinates, 1.0f,
                textureUcoordinates, 1.0f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates += middleLineDistances[0] / 100.0f;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));

                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i],
                    Vector3.Zero,
                    textureUcoordinates, 0.25f,
                    textureUcoordinates, 0.25f,
                    new Color4(0, 0, 0, 0)));
                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i] + rightPoint,
                    Vector3.Zero,
                    textureUcoordinates, 1.0f,
                     textureUcoordinates, 1.0f,
                    new Color4(0, 0, 0, 0)));

                if (i < middle.Length - 1)
                    textureUcoordinates += middleLineDistances[i] / 100.0f;
            }
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1],
                Vector3.Zero,
                textureUcoordinates, 0.25f,
                textureUcoordinates, 0.25f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] + rightPoint,
                Vector3.Zero,
                textureUcoordinates, 1.0f,
                textureUcoordinates, 1.0f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates = 0;
        }

        private static void CreateGuardRailPart2(ref Vector3[] middle, ref List<MyOwnVertex.MyPositionNormalTextured> vertices, ref List<ushort> indices, ref List<int> polyTextures, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, float textureUcoordinates)
        {
            short OffsetIndices = (short)(vertices.Count);

            polyTextures[0] += ((middle.Length - 1) * 2);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0],
                Vector3.Zero,
                textureUcoordinates, 0.25f,
                textureUcoordinates, 0.25f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] + rightPoint,
                Vector3.Zero,
                textureUcoordinates, 0.5f,
                textureUcoordinates, 0.5f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates += middleLineDistances[0] / 100.0f;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));

                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured
                    (middle[i],
                    Vector3.Zero,
                    textureUcoordinates, 0.25f,
                    textureUcoordinates, 0.25f,
                    new Color4(0, 0, 0, 0)));
                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(middle[i] + rightPoint,
                    Vector3.Zero,
                    textureUcoordinates, 0.5f,
                    textureUcoordinates, 0.5f,
                    new Color4(0, 0, 0, 0)));

                if (i < middle.Length - 1)
                    textureUcoordinates += middleLineDistances[i] / 100.0f;
            }

            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1],
                Vector3.Zero,
                textureUcoordinates, 0.25f,
                textureUcoordinates, 0.25f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] + rightPoint,
                Vector3.Zero,
                textureUcoordinates, 0.5f,
                textureUcoordinates, 0.5f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates = 0;
        }

        private static void CreateGuardRailPart3(ref Vector3[] middle, ref List<MyOwnVertex.MyPositionNormalTextured> vertices, ref List<ushort> indices, ref List<int> polyTextures, decimal anglePointOne, decimal anglePointTwo, float widthPointOne, float widthPointTwo, float inclinationPointOne, float inclinationPointTwo, float textureUcoordinates)
        {
            short OffsetIndices = (short)(vertices.Count);

            polyTextures[0] += ((middle.Length - 1) * 2);

            // This calculates the distances between each Vectors from middleline
            float[] middleLineDistances = new float[middle.Length];
            float lengthOfStreet = 0;
            middleLineDistances[0] = GeoMath.DistanceBtw2Points(middle[0], middle[1]);
            lengthOfStreet += middleLineDistances[0];
            for (int i2 = 1; i2 < middle.Length - 1; i2++)
            {
                middleLineDistances[i2] = GeoMath.DistanceBtw2Points(middle[i2], middle[i2 + 1]);
                lengthOfStreet += middleLineDistances[i2];
            }

            // here will the indicies calculate
            short point = 0;
            for (short i2 = 0; i2 < (middle.Length - 1) * 6; i2 += 6)
            {
                indices.Add((ushort)(point + OffsetIndices));
                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                indices.Add((ushort)(point + 1 + OffsetIndices));
                indices.Add((ushort)(point + 3 + OffsetIndices));
                indices.Add((ushort)(point + 2 + OffsetIndices));

                point += 2;
            }

            int i = 0;

            Vector3 rightPoint; //Is a tempoary Point
            float percentofStreet = 0;
            float streetwidth;
            float inclination = 0;

            //start
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointOne, widthPointOne, inclinationPointOne);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0],
                Vector3.Zero,
                0.5f, 0.5f,
                0.5f, 0.5f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[0] + rightPoint,
                Vector3.Zero,
                0.5f, 0.5f,
                0.5f, 0.5f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates += middleLineDistances[0] / 100;

            for (i = 1; i < (middle.Length - 1); i++)
            {
                percentofStreet += middleLineDistances[i - 1];
                streetwidth = widthPointOne - ((widthPointOne - widthPointTwo) * (percentofStreet / lengthOfStreet));
                inclination = inclinationPointOne + ((inclinationPointTwo - inclinationPointOne) * (percentofStreet / lengthOfStreet));

                rightPoint = GeoMath.makepoint(middle[i + 1], middle[i - 1], streetwidth, inclination);

                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i],
                    Vector3.Zero,
                    0.5f, 0.5f,
                    0.5f, 0.5f,
                    new Color4(0, 0, 0, 0)));
                vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                    middle[i] + rightPoint,
                    Vector3.Zero,
                    0.5f, 0.6f,
                    0.5f, 0.6f,
                    new Color4(0, 0, 0, 0)));

                if (i < middle.Length - 1)
                    textureUcoordinates += middleLineDistances[i] / 100.0f;
            }
            rightPoint = GeoMath.MakePointFromAngel(180 - anglePointTwo - 180, widthPointTwo, inclinationPointTwo);

            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1],
                Vector3.Zero,
                0.5f, 0.5f,
                0.5f, 0.5f,
                new Color4(0, 0, 0, 0)));
            vertices.Add(new MyOwnVertex.MyPositionNormalTextured(
                middle[middle.Length - 1] + rightPoint,
                Vector3.Zero,
                0.5f, 0.6f,
                0.5f, 0.6f,
                new Color4(0, 0, 0, 0)));

            textureUcoordinates = 0;
        }

        private static int GetStartOfPolygon(Mesh3dData mesh, Material materialId)
        {
            int startAdress = 0;
            for (int i = 0; i < mesh.polyTextures.Count; i++)
            {
                if (mesh.materials[i] == materialId)
                {
                    return startAdress;
                }
                else
                {
                    startAdress += mesh.polyTextures[i];
                }
            }
            return -1;
        }

        private void AddPolygons(Material material, int numberOfPolygons, Mesh3dData mesh)
        {
            int startAddress = GetStartOfPolygon(mesh, material);
            int currentPolygon = 0;
            int materialID;

            //try to find the same material in the current mesh and add the other there
            materialID = this.materials.IndexOf(material);
            if (materialID > -1)
            {
                for (int i = 0; i < materialID; i++)
                {
                    currentPolygon += this.polyTextures[i];
                }

                this.polyTextures[materialID] += numberOfPolygons;

                //add the vertices and indices;
                for (int i = 0; i < numberOfPolygons; i++)
                {
                    int offsetIndices = startAddress * 3;
                    this.indices.Insert((currentPolygon * 3), (mesh.indices[(i + startAddress) * 3]));
                    this.indices.Insert((currentPolygon * 3) + 1, (mesh.indices[(i + startAddress) * 3 + 1]));
                    this.indices.Insert((currentPolygon * 3) + 2, (mesh.indices[(i + startAddress) * 3 + 2]));

                    currentPolygon++;
                }
                return;
            }

            //When no Material is Found add the Polys at the  end of the file;
            this.materials.Add(material);
            this.polyTextures.Add(numberOfPolygons);

            for (int i = 0; i < numberOfPolygons; i++)
            {
                this.indices.Add(mesh.indices[startAddress * 3]);
                this.indices.Add(mesh.indices[startAddress * 3 + 1]);
                this.indices.Add(mesh.indices[startAddress * 3 + 2]);
                startAddress++;
            }
        }

        private void ScaleX(float scale)
        {
            for (int i = 0; i < vertices.Count; i++)
            {
                MyOwnVertex.MyPositionNormalTextured vertex = this.Vertices[i];
                vertex.X *= scale;
                this.Vertices[i] = vertex;
            }
        }

        #endregion Private Methods
    }
}